package com.mobile_base.print;

import android.util.Log;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReadableArray;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import honeywell.connection.ConnectionBase;
import honeywell.connection.Connection_Bluetooth;

public class Print extends ReactContextBaseJavaModule {

    public static final Integer PRINTER_TIME_OUT = 5000;

    private ConnectionBase conn = null;

    private Socket socket = null;

    public Print(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "Print";
    }


    /**
     * @param macAddress 打印机mac地址
     * @param cmdList    打印机指令
     */
    private void bluePrint(String macAddress, List<String> cmdList, Promise promise) {
        try {
            conn = Connection_Bluetooth.createClient(macAddress, false);
            boolean connected = false;
            for (int i = 1; i < 4; i++) {
                if (!conn.getIsOpen()) {
                    conn.open();
                    connected = true;
                    break;
                }
            }
            if (!connected) {
                promise.reject(new Error("未连接到Socket，请重试!"));
                return;
            }
            for (String cmd : cmdList) {
                conn.write(cmd);
            }
        } catch (Exception e) {
            promise.reject(new Error("打印机连接异常：" + e));
        } finally {
            if (conn!= null && conn.getIsOpen()) {
                conn.close();
            }
        }
    }

    /**
     * @param ipAddress 打印机ip地址
     * @param cmdList   打印机指令
     */
    private void wlanPrint(String ipAddress, List<String> cmdList, Promise promise) {
        printerReachable(ipAddress, promise);
        try {
            socket = new Socket(ipAddress, 9100);
            OutputStream out = socket.getOutputStream();
            for (String cmd : cmdList) {
                out.write(cmd.getBytes());
                out.flush();
            }
        } catch (IOException e) {
            promise.reject(new Error("打印机通讯异常：" + e));
        } finally {
            if (socket != null) {
                try {
                    socket.shutdownOutput();
                    socket.shutdownInput();
                    socket.close();
                } catch (IOException e) {
                    promise.reject(new Error("打印机连接关闭失败：" + e));
                }
            }
        }
    }

    /**
     * @param targetDevice 打印机地址
     * @param content      打印机指令
     * @param promise      返回参数
     */
    @ReactMethod
    public void printCmdList(String type, String targetDevice, ReadableArray content, Promise promise) {
        if (type == null || type.length() == 0) {
            promise.reject(new Error("打印机类型为空，请检查!"));
        }
        if (targetDevice == null || targetDevice.length() == 0) {
            promise.reject(new Error("打印设备地址为空，请检查!"));
        }
        if (content.size() <= 0) {
            promise.reject(new Error("打印指令为空，请检查!"));
        }
        List<String> cmdList = new ArrayList<>();
        for (int i = 0; i < content.size(); i++) {
            cmdList.add(content.getString(i));
        }
        if ("WLAN".equals(type)) {
            wlanPrint(targetDevice, cmdList, promise);
        } else if ("BLUETOOTH".equals(type)) {
            bluePrint(targetDevice, cmdList, promise);
        } else {
            promise.reject(new Error("打印类型不为蓝牙或无线，请检查!"));
        }
    }

    /**
     * @param targetDevice 打印机地址
     * @param content      打印机指令
     */
    @ReactMethod
    public void printCmd(String type, String targetDevice, String content, Promise promise) {
        if (type == null || type.length() == 0) {
            promise.reject(new Error( "打印机类型为空，请检查!"));
        }
        if (targetDevice == null || targetDevice.length() == 0) {
            promise.reject(new Error("打印设备地址为空，请检查!"));
        }
        if (content == null || content.length() == 0) {
            promise.reject(new Error("打印指令为空，请检查!"));
        }
        List<String> cmdList = new ArrayList<>();
        cmdList.add(content);
        if ("WLAN".equals(type)) {
            wlanPrint(targetDevice, cmdList, promise);
        } else if ("BLUETOOTH".equals(type)) {
            bluePrint(targetDevice, cmdList, promise);
        } else {
            promise.reject(new Error("打印类型不为蓝牙或无线，请检查!"));
        }
    }

    /**
     * @param ipAddress 打印地址
     */
    private void printerReachable(String ipAddress, Promise promise) {
        try {
            InetAddress address = InetAddress.getByName(ipAddress);
            if (address instanceof java.net.Inet4Address) {
                Log.i("PrintInfo", ipAddress + " is ipv4 address");
            } else if (address instanceof java.net.Inet6Address) {
                Log.i("PrintInfo", ipAddress + " is ipv6 address");
            } else {
                promise.reject(new Error("IP地址" + ipAddress + "无法识别！"));
            }
            if (address.isReachable(PRINTER_TIME_OUT)) {
                Log.i("PrintInfo", "SUCCESS - ping " + ipAddress + " with no interface specified");
            } else {
                promise.reject(new Error("打印机连接异常失败！"));
            }
        } catch (Exception e) {
            promise.reject(new Error("打印机连接异常：" + e));
        }
    }
}




